package com.ruoyi.swla2.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.swla2.domain.*;
import com.ruoyi.swla2.mapper.*;
import com.ruoyi.swla2.model.MultiTerminalDataModel;
import com.ruoyi.swla2.model.TerminalsModel;
import com.ruoyi.swla2.service.IPressureConfigurationService;
import com.ruoyi.swla2.service.ITerminalHistoryDataService;
import com.ruoyi.swla2.service.IWarnService;
import com.ruoyi.swla2.service.IWarnSsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 大表档案Service业务层处理
 *
 * @author gdqt
 * @date 2023-06-16
 */
@Service
public class PressureConfigurationServiceImpl extends ServiceImpl<PressureConfigurationMapper, PressureConfiguration> implements IPressureConfigurationService {

    @Autowired
    private TerminalHistoryDataMapper terminalHistoryDataMapper;

    @Autowired
    private IWarnService warnService;

    @Autowired
    private IWarnSsService warnSsService;

    /**
     * @Description: 多表压差报警
     * @date: 2025/2/27 09:27
     * @author: zt
     */
    @Override
    public void initMultiMonitorWarn(Integer minutes) {
        try {
            if(minutes == null || minutes <= 0){ return; }
            Date endDate = new Date();
            //往前推多少分钟
            Date startDate = DateUtil.offsetMinute(endDate, -minutes);

            Date sTime = DateUtil.beginOfDay(startDate).toJdkDate();
            Date eTime = DateUtil.endOfDay(endDate).toJdkDate();
            //1.查询所有多表配置数据
            List<PressureConfiguration> configList = this.list();
            //判断配置是否为空
            if(configList != null && !configList.isEmpty()){
                //所有多表压差配置的id
                List<Long> configIds= configList.stream().map(PressureConfiguration::getId).collect(Collectors.toList());
                List<String> terminalOne = configList.stream().map(PressureConfiguration::getTerminalIdOne).distinct().collect(Collectors.toList());
                List<String> terminalTwo = configList.stream().map(PressureConfiguration::getTerminalIdTwo).distinct().collect(Collectors.toList());
                terminalOne.addAll(terminalTwo);
                //所有压力设备ID
                List<String> allTerminalList = terminalOne.stream().distinct().collect(Collectors.toList());
                //2.查询大表历史数据-开始时间，结束时间
                List<TerminalHistoryData> terminalHistoryDataList = terminalHistoryDataMapper.selectList(new LambdaQueryWrapper<TerminalHistoryData>()
                        .in(TerminalHistoryData::getTerminalID,allTerminalList)
                        .ge(TerminalHistoryData::getReadDate,startDate)
                        .le(TerminalHistoryData::getReadDate,endDate));
                //判断有没有历史数据，有历史数据继续执行下一步
                if(terminalHistoryDataList != null && !terminalHistoryDataList.isEmpty()){
                    //3.查询实时报警表-未处理
                    List<WarnSs> warnSsList = warnSsService.selectListForTask(configIds);
                    //4.查询历史报警表-当天未处理
                    List<Warn> warnList = warnService.selectListForTask(configIds,sTime,eTime);
                    //5.循环多表压差配置
                    for(PressureConfiguration config : configList){
                        String id = String.valueOf(config.getId());
                        String terminalIdOne = config.getTerminalIdOne();
                        String terminalIdTwo = config.getTerminalIdTwo();
                        double standardPressure = config.getStandardPressure().doubleValue();

                        List<WarnSs> theWarnSsList = new ArrayList<>();
                        List<Warn> theWarnList = new ArrayList<>();
                        //6.指定报警对象ID的历史报警数据
                        if(warnList != null && !warnList.isEmpty()){
                            theWarnList = warnList.stream().filter(w -> w.getTargetID().equals(id)).collect(Collectors.toList());
                        }
                        //7.指定报警对象ID的实时报警数据
                        if(warnSsList != null && !warnSsList.isEmpty()){
                            theWarnSsList = warnSsList.stream().filter(w -> w.getTargetID().equals(id)).collect(Collectors.toList());
                        }
                        //8.历史数据处理
                        List<MultiTerminalDataModel> multiDataList = dealHistoryData(terminalIdOne,terminalIdTwo,terminalHistoryDataList);
                        //如果没数据的话，就不用走后续流程了
                        if(!multiDataList.isEmpty()){
                            String warnStartTime = null;//此次报警开始时间
                            String warnEndTime = null;//此次报警结束时间
                            BigDecimal warnValue = null;
                            boolean first = true;
                            //循环数据
                            for(MultiTerminalDataModel multiData : multiDataList){
                                //两个压力表差值可能为负数，需要求绝对值再跟压差标准值比较
                                //大于标准值-报警
                                if(multiData.getValue() != null && Math.abs(multiData.getValue().doubleValue())>=standardPressure){
                                    if(first){
                                        warnStartTime = multiData.getDataTime();
                                        first = false;
                                    }
                                    warnEndTime = multiData.getDataTime();
                                    warnValue = multiData.getValue();
                                }
                            }
                            //报警开始时间不为null，说明有报警
                            if(warnStartTime != null){
                                //实时报警
                                WarnSs warnSs = new WarnSs();
                                if(!theWarnSsList.isEmpty()){
                                    warnSs = theWarnSsList.get(0);
                                    warnSs.setFreezetime(warnStartTime);
                                    warnSs.setWarnValue(warnValue);
                                    warnSs.setReferenceValue(config.getStandardPressure());
                                    warnSs.setRecentlyWartTime(DateUtil.parseDateTime(warnEndTime));
                                    warnSsService.updateForTask(warnSs);
                                }else {
                                    warnSs.setTenantId(config.getTenantId());
                                    warnSs.setTargetID(id);
                                    warnSs.setTargetType(4L);
                                    warnSs.setWarnParamType(10L);
                                    warnSs.setWarnType(1L);
                                    warnSs.setWarnStatus(0L);
                                    warnSs.setHandleStatus(0L);
                                    warnSs.setFreezetime(warnStartTime);
                                    warnSs.setWarnValue(warnValue);
                                    warnSs.setReferenceValue(config.getStandardPressure());
                                    warnSs.setRecentlyWartTime(DateUtil.parseDateTime(warnEndTime));
                                    warnSs.setStartTime(DateUtil.parseDateTime(warnStartTime));
                                    warnSsService.insertForTask(warnSs);
                                }
                                //历史报警报警
                                Warn warn = new Warn();
                                if(!theWarnList.isEmpty()){
                                    warn = theWarnList.get(0);
                                    warn.setFreezetime(warnStartTime);
                                    warn.setWarnValue(warnValue);
                                    warn.setReferenceValue(config.getStandardPressure());
                                    warn.setRecentlyWartTime(DateUtil.parseDateTime(warnEndTime));
                                    warnService.updateForTask(warn);
                                }else {
                                    warn.setTenantId(config.getTenantId());
                                    warn.setTargetID(id);
                                    warn.setTargetType(4L);
                                    warn.setWarnParamType(10L);
                                    warn.setWarnType(1L);
                                    warn.setWarnStatus(0L);
                                    warn.setHandleStatus(0L);
                                    warn.setFreezetime(warnStartTime);
                                    warn.setWarnValue(warnValue);
                                    warn.setReferenceValue(config.getStandardPressure());
                                    warn.setRecentlyWartTime(DateUtil.parseDateTime(warnEndTime));
                                    warn.setStartTime(DateUtil.parseDateTime(warnStartTime));
                                    warnService.insertForTask(warn);
                                }
                            }
                        }
                    }
                }
            }
        }catch (Exception e){
            System.out.println(e.fillInStackTrace());
        }
    }

    /**
     * @Description: 历史数据处理
     * @date: 2025/2/27 14:04
     * @author: zt
     */
    private List<MultiTerminalDataModel> dealHistoryData(String terminalId1,String terminalId2,List<TerminalHistoryData> dataList){
        //返回数组
        List<MultiTerminalDataModel> resList = new ArrayList<>();
        List<TerminalHistoryData> theHisDataList = dataList.stream().filter(item-> item.getTerminalID().equals(terminalId1) || item.getTerminalID().equals(terminalId2)).collect(Collectors.toList());
        //如果没数据的话，就不用走后续流程了
        if(!theHisDataList.isEmpty()){
            //时间数组
            List<Date> timeList = dataList.stream().map(TerminalHistoryData::getReadDate).distinct().sorted(Date::compareTo).collect(Collectors.toList());
            //根据时间分组
            Map<Date,List<TerminalHistoryData>> dateListMap = dataList.stream().collect(Collectors.groupingBy(TerminalHistoryData::getReadDate));
            for (Date date : timeList) {
                MultiTerminalDataModel tempData = new MultiTerminalDataModel();
                List<TerminalHistoryData> terminalHistoryDataList = dateListMap.get(date);
                for (TerminalHistoryData terminalHistoryData : terminalHistoryDataList) {
                    //设备A
                    if(terminalHistoryData.getTerminalID().equals(terminalId1)){
                        tempData.setTerminalId1(terminalHistoryData.getTerminalID());
                        tempData.setTerminalName1(terminalHistoryData.getTerminalName());
                        tempData.setPressure1(terminalHistoryData.getPressure());
                    }
                    //设备B
                    if(terminalHistoryData.getTerminalID().equals(terminalId2)){
                        tempData.setTerminalId2(terminalHistoryData.getTerminalID());
                        tempData.setTerminalName2(terminalHistoryData.getTerminalName());
                        tempData.setPressure2(terminalHistoryData.getPressure());
                    }
                }
                if(!StringUtils.isEmpty(tempData.getTerminalId1()) && !StringUtils.isEmpty(tempData.getTerminalId2())){
                    if(tempData.getPressure1()!=null && tempData.getPressure2()!=null){
                        BigDecimal bd = BigDecimal.valueOf(tempData.getPressure1().doubleValue() - tempData.getPressure2().doubleValue()).setScale(2, RoundingMode.HALF_UP);
                        tempData.setValue(bd);
                    }else {
                        tempData.setValue(BigDecimal.valueOf(0));
                    }
                } else if (StringUtils.isEmpty(tempData.getTerminalId1())) {
                    tempData.setTerminalId1(terminalId1);
                } else if (StringUtils.isEmpty(tempData.getTerminalId2())) {
                    tempData.setTerminalId2(terminalId2);
                }
                tempData.setDataTime(DateUtil.formatDateTime(date));
                resList.add(tempData);
            }
        }
        return resList;
    }

}
